package com.example.searchcenter.center;

import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import com.example.searchcenter.R;
import com.example.searchcenter.helper.JSONParser;
import com.example.searchcenter.model.CenterItemModel;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

import android.app.Dialog;
import android.content.Intent;
import android.graphics.PointF;
import android.location.Criteria;
import android.location.Location;
import android.location.LocationManager;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.view.View;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.Toast;

public class NearbyCenters extends FragmentActivity {

	/**
	 * @param args
	 */
	GoogleMap mGoogleMap;
	private static double mLatitude = 0;
	private static double mLongitude = 0;
	private static String url = "http://tinhnguyen.edu.vn/apis/placesNearby";
	private static int radius = 2000;
	private static double clat = 0;
	private static double clng = 0;
	private static PointF center;
	// private String id_center;
	// private String name_center;
	ArrayList<CenterItemModel> centerNearbyList = new ArrayList<CenterItemModel>();

	// JSON Node names
	static final String TAG_SUCCESS = "success";
	static final String TAG_CENTERS = "centers";
	static final String TAG_ID_CENTER = "cid";
	static final String TAG_NAME = "name";
	static final String TAG_THUMBNAIL = "thumbnailImageUrl";
	static final String TAG_NO = "no";
	static final String TAG_STREET = "street";
	static final String TAG_WARD = "ward";
	static final String TAG_DISTRICT = "district";
	static final String TAG_CITY = "city";
	static final String TAG_CREATEDATE = "createDate";
	static final String TAG_DESCRIPTION = "description";
	static final String TAG_PRESENTER = "presenter";
	static final String TAG_PHONE = "phone";
	static final String TAG_WEBSITE = "website";
	static final String TAG_EMAIL = "email";
	static final String TAG_TYPE = "type";
	static final String TAG_LAT = "lat";
	static final String TAG_LONG = "long";
	JSONArray arrayJsonCenter = null;
	JSONObject jsonobject;
	JSONArray jsonarray;

	// String condition
	private static String strCondition = "";

	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.centersnearby);
		// Getting Google Play availability status
		int status = GooglePlayServicesUtil
				.isGooglePlayServicesAvailable(getBaseContext());

		if (status != ConnectionResult.SUCCESS) { // Google Play Services are
													// not available

			int requestCode = 10;
			Dialog dialog = GooglePlayServicesUtil.getErrorDialog(status, this,
					requestCode);
			dialog.show();

		} else { // Google Play Services are available\

			// Getting reference to the SupportMapFragment
			SupportMapFragment fragment = (SupportMapFragment) getSupportFragmentManager()
					.findFragmentById(R.id.map);

			// Getting Google Map
			mGoogleMap = fragment.getMap();

			// Enabling MyLocation in Google Map
			mGoogleMap.setMyLocationEnabled(true);

			// Getting LocationManager object from System Service
			// LOCATION_SERVICE
			LocationManager locationManager = (LocationManager) getSystemService(LOCATION_SERVICE);

			// Creating a criteria object to retrieve provider
			Criteria criteria = new Criteria();

			// Getting the name of the best provider
			String provider = locationManager.getBestProvider(criteria, true);

			// Getting Current Location From GPS
			Location location = locationManager.getLastKnownLocation(provider);

			if (location != null) {
				onLocationChanged(location);
			}

			float x = (float) location.getLatitude();
			float y = (float) location.getLongitude();

			/*
			 * float x = (float) clat; float y = (float) clng;
			 */
			center = new PointF(x, y);
			final double mult = 1; // mult = 1.1; is more reliable
			PointF p1 = calculateDerivedPosition(center, mult * radius, 0);
			PointF p2 = calculateDerivedPosition(center, mult * radius, 90);
			PointF p3 = calculateDerivedPosition(center, mult * radius, 180);
			PointF p4 = calculateDerivedPosition(center, mult * radius, 270);

			strCondition = " WHERE v.lat" + " > " + String.valueOf(p3.x)
					+ " AND v.lat" + " < " + String.valueOf(p1.x)
					+ " AND v.long" + " < " + String.valueOf(p2.y)
					+ " AND v.long" + " > " + String.valueOf(p4.y);

			// Toast.makeText(getApplicationContext(), strCondition,
			// Toast.LENGTH_LONG).show();
			Log.w("condition", strCondition);
			new ListCenters().execute();

			// add marker to maps
			// addmarkertomap();

			// get and set autocomplete from layout
			final AutoCompleteTextView currentloc = (AutoCompleteTextView) findViewById(R.id.from);
			// currentloc.setText("Vị trí hiện tại");
			currentloc.setAdapter(new PlacesAutoCompleteAdapter(this,
					android.R.layout.simple_dropdown_item_1line));

			Button find = (Button) findViewById(R.id.btn_find);
			find.setOnClickListener(new View.OnClickListener() {

				@Override
				public void onClick(View v) {
					try {
						getLatLongFromAddress(currentloc.getText().toString());
					} catch (UnsupportedEncodingException e) {
						e.printStackTrace();
					}
					float x = (float) clat;
					float y = (float) clng;
					center = new PointF(x, y);
					final double mult = 1; // mult = 1.1; is more reliable
					PointF p1 = calculateDerivedPosition(center, mult * radius,
							0);
					PointF p2 = calculateDerivedPosition(center, mult * radius,
							90);
					PointF p3 = calculateDerivedPosition(center, mult * radius,
							180);
					PointF p4 = calculateDerivedPosition(center, mult * radius,
							270);

					strCondition = " WHERE v.lat" + " > "
							+ String.valueOf(p3.x) + " AND v.lat" + " < "
							+ String.valueOf(p1.x) + " AND v.long" + " < "
							+ String.valueOf(p2.y) + " AND v.long" + " > "
							+ String.valueOf(p4.y);

					centerNearbyList.clear();
					new ListCenters().execute();

				}
			});
			mGoogleMap
					.setOnInfoWindowClickListener(new GoogleMap.OnInfoWindowClickListener() {

						@Override
						public void onInfoWindowClick(Marker mk) {
							for (int i = 0; i < centerNearbyList.size(); i++) {
								if (centerNearbyList.get(i).getCenterName()
										.equals(mk.getTitle())) {

									Intent intent = new Intent(
											NearbyCenters.this,
											DetailsCenter.class);
									intent.putExtra(TAG_ID_CENTER,
											centerNearbyList.get(i)
													.getCenterId());
									startActivity(intent);
									Toast.makeText(
											getApplicationContext(),
											"Bạn đã chọn  "
													+ centerNearbyList.get(i)
															.getCenterName(),
											Toast.LENGTH_SHORT).show();
								}
							}

						}
					});
			/*
			 * Button clear = (Button) findViewById(R.id.clear_text);
			 * clear.setOnClickListener(new View.OnClickListener() {
			 * 
			 * @Override public void onClick(View v) { currentloc.setText(""); }
			 * });
			 */

		}
	}

	private class ListCenters extends AsyncTask<String, String, JSONObject> {
		@Override
		protected void onPreExecute() {
			super.onPreExecute();

		}

		@Override
		protected JSONObject doInBackground(String... args) {
			JSONParser jParser = new JSONParser();
			// Building Parameters
			List<NameValuePair> params = new ArrayList<NameValuePair>();
			params.add(new BasicNameValuePair("strwhere", strCondition));

			// getting product details by making HTTP request
			// Note that product details url will use GET request
			jsonobject = jParser.makeHttpRequest(url, "GET", params);

			return jsonobject;
		}

		@Override
		protected void onPostExecute(JSONObject json) {
			// pDialog.dismiss();
			try {
				// Getting JSON Array from URL
				Log.w("JSON", json.toString());

				arrayJsonCenter = json.getJSONArray(TAG_CENTERS);

				for (int i = 0; i < arrayJsonCenter.length(); i++) {

					JSONObject c = arrayJsonCenter.getJSONObject(i);
					// Storing JSON item in a Variable
					String cid = c.getString(TAG_ID_CENTER);
					String name = c.getString(TAG_NAME);
					String thumbnail = c.getString(TAG_THUMBNAIL);
					String no = c.getString(TAG_NO);
					String street = c.getString(TAG_STREET);
					String ward = c.getString(TAG_WARD);
					String district = c.getString(TAG_DISTRICT);
					String city = c.getString(TAG_CITY);
					String createDate = c.getString(TAG_CREATEDATE);
					String lat = c.getString(TAG_LAT);
					String lng = c.getString(TAG_LONG);

					// String address
					String addr = "Số " + no + " ,Đường " + street
							+ " ,Phường/xã " + ward + " ,Quận/huyện "
							+ district + " ,thành phố " + city;

					CenterItemModel centerItem = new CenterItemModel(cid, name,
							addr, createDate, thumbnail, lat, lng);
					centerNearbyList.add(centerItem);

				}
				Log.w("lenght", String.valueOf(arrayJsonCenter.length()));
				addmarkertomap();

			} catch (JSONException e) {
				e.printStackTrace();
			}
		}
	}

	/**
	 * Calculates the end-point from a given source at a given range (meters)
	 * and bearing (degrees). This methods uses simple geometry equations to
	 * calculate the end-point.
	 * 
	 * @param point
	 *            Point of origin
	 * @param range
	 *            Range in meters
	 * @param bearing
	 *            Bearing in degrees
	 * @return End-point from the source given the desired range and bearing.
	 */
	public static PointF calculateDerivedPosition(PointF point, double range,
			double bearing) {
		double EarthRadius = 6371000; // m

		double latA = Math.toRadians(point.x);
		double lonA = Math.toRadians(point.y);
		double angularDistance = range / EarthRadius;
		double trueCourse = Math.toRadians(bearing);

		double lat = Math.asin(Math.sin(latA) * Math.cos(angularDistance)
				+ Math.cos(latA) * Math.sin(angularDistance)
				* Math.cos(trueCourse));

		double dlon = Math.atan2(
				Math.sin(trueCourse) * Math.sin(angularDistance)
						* Math.cos(latA),
				Math.cos(angularDistance) - Math.sin(latA) * Math.sin(lat));

		double lon = ((lonA + dlon + Math.PI) % (Math.PI * 2)) - Math.PI;

		lat = Math.toDegrees(lat);
		lon = Math.toDegrees(lon);

		PointF newPoint = new PointF((float) lat, (float) lon);

		return newPoint;

	}

	public void onLocationChanged(Location location) {
		mLatitude = location.getLatitude();
		mLongitude = location.getLongitude();
		LatLng latLng = new LatLng(mLatitude, mLongitude);

		mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
		mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(12));
		mGoogleMap.addMarker(new MarkerOptions()
				.position(latLng)
				.title("current location!!!")
				.icon(BitmapDescriptorFactory
						.defaultMarker(BitmapDescriptorFactory.HUE_AZURE)));
	}

	public static void getLatLongFromAddress(String youraddress) throws UnsupportedEncodingException {
		String uri = "http://maps.google.com/maps/api/geocode/json?address="
				+ URLEncoder.encode(youraddress, "UTF-8") + "&sensor=false";
		HttpGet httpGet = new HttpGet(uri);
		HttpClient client = new DefaultHttpClient();
		HttpResponse response;
		StringBuilder stringBuilder = new StringBuilder();

		try {
			response = client.execute(httpGet);
			HttpEntity entity = response.getEntity();
			InputStream stream = entity.getContent();
			int b;
			while ((b = stream.read()) != -1) {
				stringBuilder.append((char) b);
			}
		} catch (ClientProtocolException e) {
			e.printStackTrace();
		} catch (IOException e) {
			e.printStackTrace();
		}

		JSONObject jsonObject = new JSONObject();
		try {
			jsonObject = new JSONObject(stringBuilder.toString());

			clng = ((JSONArray) jsonObject.get("results")).getJSONObject(0)
					.getJSONObject("geometry").getJSONObject("location")
					.getDouble("lng");

			clat = ((JSONArray) jsonObject.get("results")).getJSONObject(0)
					.getJSONObject("geometry").getJSONObject("location")
					.getDouble("lat");

			Log.d("latitude", String.valueOf(clat));
			Log.d("longitude", String.valueOf(clng));

		} catch (JSONException e) {
			e.printStackTrace();
		}

	}

	public void addmarkertomap() {
		// Add marker to maps

		// Clears all the existing markers
		mGoogleMap.clear();
		if (clat != 0) {
			LatLng clatLng = new LatLng(clat, clng);

			Marker mklocaiton = mGoogleMap.addMarker(new MarkerOptions()
					.position(clatLng)
					.title("Vị trí đã nhập")
					.icon(BitmapDescriptorFactory
							.fromResource(R.drawable.marker_current)));

			mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(clatLng));
			mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(12));
			mklocaiton.showInfoWindow();
			clat = 0;
			clng = 0;
		} else {
			LatLng latLng = new LatLng(mLatitude, mLongitude);

			mGoogleMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
			mGoogleMap.animateCamera(CameraUpdateFactory.zoomTo(12));
			Marker mkloction = mGoogleMap.addMarker(new MarkerOptions()
					.position(latLng)
					.title("Vị trí hiện tại")
					.icon(BitmapDescriptorFactory
							.fromResource(R.drawable.marker_current)));
			mkloction.showInfoWindow();
		}

		for (int i = 0; i < centerNearbyList.size(); i++) {

			// Creating a marker
			MarkerOptions markerOptions = new MarkerOptions();

			// Getting a place from the places list
			CenterItemModel hmPlace = centerNearbyList.get(i);

			// Getting latitude of the place
			double lat = Double.parseDouble(hmPlace.getLat());

			// Getting longitude of the place
			double lng = Double.parseDouble(hmPlace.getLng());

			// Getting name
			String name_center = hmPlace.getCenterName();

			/*
			 * // Getting vicinity String vicinity = hmPlace.get("vicinity");
			 */
			LatLng latLng = new LatLng(lat, lng);

			// Setting the position for the marker
			markerOptions.position(latLng);

			// Setting the title for the marker.
			// This will be displayed on taping the marker
			markerOptions.title(name_center);
			markerOptions.flat(true);
			// Placing a marker on the touched position

			mGoogleMap.addMarker(markerOptions.icon(BitmapDescriptorFactory
					.fromResource(R.drawable.maker)));
		}
	}
}
